/*
SteelNzb
Copyright (C) 2008  Wessel v. Staal

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/* Wessel van Staal */
/* Abstract filesystem */

#include "filesys.h"
#include "global.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#if defined(WIN32) || defined(WINCE)
#include <windows.h>
#define stricmp _stricmp
#define unlink _unlink
#else
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#define stricmp strcasecmp
#endif

void filesys_moveFile(const char* source, const char* target)
{
#ifdef WIN32
	TCHAR sourceW[1024];
	TCHAR targetW[1024];

	if ( MultiByteToWideChar(CP_ACP, 0, source, -1, sourceW, 1024) == 0 )
	{
		PRINTERROR("FileSys::MoveFile");
		exit(1);
	}

	if ( MultiByteToWideChar(CP_ACP, 0, target, -1, targetW, 1024) == 0 )
	{
		PRINTERROR("FileSys::MoveFile");
		exit(1);
	}

	if ( MoveFile(sourceW, targetW) == 0 )
	{
		PRINTERROR("FileSys::MoveFile: Could not move file");
	}
#else
	if ( rename(source, target) != 0 )
	{
		PRINTERROR("FileSys::MoveFile: Could not move file");
	}
#endif
}

void filesys_deleteFile(const char* path)
{
	#ifdef WIN32
	TCHAR full_pathW[1024];

if ( MultiByteToWideChar(CP_ACP, 0, path, -1, full_pathW, 1024) == 0 )
{
	PRINTERROR("Manager::DownloadArticle");
	exit(1);
}
DeleteFile(full_pathW);
#else
	if ( unlink(path) != 0 )
	{
		PRINTERROR("Manager::Could not delete file");
	}
#endif
}

int filesys_itemExists(const char* name)
{
#if WIN32
	TCHAR path[1024];

	if ( MultiByteToWideChar(CP_ACP, 0, name, -1, path, 1024) == 0 )
	{
		PRINTERROR("FileSys::ItemExists");
		exit(1);
	}

	return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;

#else
	struct stat st;

	return stat(name,&st) == 0;

#endif
}
/**
	Reads entries from directory
	@param dirname Path to directory
	@param count Out: number of entries
	@returns pointer to array of pointers to entries
*/
filesys_entry** filesys_readDirectory(const char* dirname, int* count)
{
	filesys_entry** entries = NULL;
	filesys_entry* entry = NULL;
#ifdef WIN32

	HANDLE hFirstFile;
	WIN32_FIND_DATA results;
	TCHAR path[1024];
	TCHAR dirnameW[512];

	if ( MultiByteToWideChar(CP_ACP, 0, dirname, -1, dirnameW, 1024) == 0 )
	{
		PRINTERROR("FileSys::ReadDirectory");
		exit(1);
	}

#ifdef WINCE
	swprintf(path, L"%s*", dirnameW);
#else
	swprintf(path, 1024, L"%s*", dirnameW);
#endif

	if ( (hFirstFile = FindFirstFile(path, &results)) == INVALID_HANDLE_VALUE )
	{
		int error = GetLastError();
		if ( error != 18 )
			return NULL;
	}
	*count = 0;

	do
	{
		if ( (entry = malloc(sizeof(filesys_entry))) == NULL )
		{
			perror("FileSys::ReadDirectory");
			exit(1);
		}

		if ( (entries = realloc(entries, sizeof(filesys_entry*) * ++(*count))) == NULL )
		{
			perror("FileSys::ReadDirectory");
			exit(1);
		}

		memset(entry, 0, sizeof(filesys_entry));

		entries[*count-1] = entry;

		if ( (results.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
			entry->type = FILESYS_DIRECTORY;
		else
			entry->type = FILESYS_FILE;

		if ( WideCharToMultiByte(CP_ACP, 0, results.cFileName, -1, entry->name, sizeof(entry->name), NULL, NULL) == 0 )
		{
			PRINTERROR("FileSys::ReadDirectory");
			exit(1);
		}
	}
	while ( FindNextFile(hFirstFile, &results) );

	FindClose(hFirstFile);
#else
	
	DIR* dirptr = NULL;
	struct dirent* direntry = NULL;

	*count = 0;

	if ( (dirptr = opendir(dirname)) != NULL )
	{
		while ( (direntry = readdir(dirptr)) != NULL )
		{
			if ( (entry = malloc(sizeof(filesys_entry))) == NULL )
			{
				perror("FileSys::ReadDirectory");
				exit(1);
			}

			if ( (entries = realloc(entries, sizeof(filesys_entry*) * ++(*count))) == NULL )
			{
				perror("FileSys::ReadDirectory");
				exit(1);
			}

			memset(entry, 0, sizeof(filesys_entry));

			entries[*count-1] = entry;

			entry->type = FILESYS_FILE;

			strcpy(entry->name, direntry->d_name);
		}

		closedir(dirptr);
	}

#endif

	return entries;
}
